﻿using System;
using System.Text;
using System.IO;
using System.Net;
using System.Web;
using System.Windows.Forms;
using Wagner.Utilities;

namespace Wagner.SharePoint.Utilities
{
	/// <summary>
	/// SharePoint Developer Utility
	/// http://spdev.codeplex.com/
	/// </summary>
	internal class SPDev : OperationBase
	{
		internal enum SPDevOperation
		{
			Unknown,
			Help,
			FeatCheck,
			Gac,
			GenWS,
			ListJobs,
			RecycleAppPool,
			RestartTimer,
			RunJob,
			SchJob
		}
		
		[STAThread]
		static void Main(string[] args)
		{
			new SPDev().Run();
		}

		private SPDev()
		{}

		private string Name
		{
			get { return "SPDev - SharePoint Developer Utility"; }
		}

		private string License
		{
			get { return "GNU General Public License version 2 (GPLv2)"; }
		}

		private void Run()
		{
			try
			{
				if (Args["debug"] == "true" || Args["help"] == "true")
				{
					Console.WriteLine(Name);
					Console.WriteLine("Created by Mark Wagner");
					Console.WriteLine("Version: " + Version.ToString());
					Console.WriteLine("License: " + License);
					Console.WriteLine();
				}
				else
					Console.WriteLine("SPDev, " + Version.ToString() + ", Created by Mark Wagner");

				if (Args["?"] != null || Args["help"] != null || Args["o"] == null)
				{
					// An operation other other than "help" was specified
					SPDev.ShowHelp(GetOperationEnum(Args["help"]));
				}
				else
				{
					// Execute the operation
					string opCode = Args["o"];
					OperationBase opCmd = GetOperationInstance(opCode);
					opCmd.Run();
				}
			}
			catch (Exception ex)
			{
				Log(ex);
			}

			if (Args["pause"] == "true")
			{
				try
				{
					Console.WriteLine("Press any key to continue.");
					Console.ReadKey();
				}
				catch (System.InvalidOperationException)
				{
					// This exception is ignored to prevent crashing VS while running 
					// in the Visual Studio IDE. This is caused when the trying to read
					////// input when no input is allows, such as in the Output window in VS.
				}
			}
		}

		private static SPDevOperation GetOperationEnum(string operation)
		{
			if (string.IsNullOrEmpty(operation))
				return SPDevOperation.Unknown;

			if (operation.Equals("true", StringComparison.InvariantCultureIgnoreCase))
				return SPDevOperation.Help;

			try
			{
				SPDevOperation op = (SPDevOperation)Enum.Parse(typeof(SPDevOperation), operation, true);
				return op;
			}
			catch
			{
				return SPDevOperation.Unknown;
			}
		}

		internal static OperationBase GetOperationInstance(string opCode)
		{
			SPDevOperation op = GetOperationEnum(opCode);
			return GetOperationInstance(op);
		}

		internal static OperationBase GetOperationInstance(SPDevOperation op)
		{
			switch (op)
			{
				case SPDevOperation.FeatCheck:
					return new FeatCheck();
				case SPDevOperation.Gac:
					return new Gac();
				case SPDevOperation.GenWS:
					return new GenWS();
				case SPDevOperation.ListJobs:
					return new ListJobs();
				case SPDevOperation.RecycleAppPool:
					return new RecycleAppPool();
				case SPDevOperation.RestartTimer:
					return new RestartTimer();
				case SPDevOperation.RunJob:
					return new RunJob();
				case SPDevOperation.SchJob:
					return new SchJob();
				default:
					ShowHelp(SPDevOperation.Help);
					throw new Exception("Operation unknown: " + op.ToString());
			}
		}

		internal static void ShowHelp(SPDevOperation op)
		{
			if (op == SPDevOperation.Help)
				// General SPDev help
				Console.Write(HelpOperations);
			else
			{
				// Specific operation help
				OperationBase o = GetOperationInstance(op);
				Console.Write(o.HelpDetail);
			}
		}

		internal static string HelpOperations
		{
			get
			{
				string summary = "";

				// Iterate through each SPDevOperation enum value to get an instance of 
				// each operation class to get the help summary.
				foreach (SPDevOperation opEnum in System.Enum.GetValues(typeof(SPDevOperation)))
				{
					if (opEnum != SPDevOperation.Unknown && opEnum != SPDevOperation.Help)
						summary = summary + GetOperationInstance(opEnum).HelpSummary + "\n";
				}

				string help = string.Format(@"
SPDev.exe Syntax Help:
Usage:
  SPDev.exe -o <operation> [<parameters>]

Help:
  SPDev.exe -? | -help <operation>

Operations:
{1}

Examples:
 SPDev.exe -help
 SPDev.exe -help GenWS
 SPDev.exe -help RecycleAppPool
", Version.ToString(), summary);

				return help;
			}
		}

	}	
}

